package top.songxs.yygh.hosp.service.impl;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import top.songxs.yygh.cmn.client.DictFeignClient;
import top.songxs.yygh.common.exp.DiyException;
import top.songxs.yygh.common.utils.MD5;
import top.songxs.yygh.hosp.repository.HospitalRepository;
import top.songxs.yygh.hosp.service.HospitalService;
import top.songxs.yygh.hosp.service.HospitalSetService;
import top.songxs.yygh.hosp.util.AckUtil;
import top.songxs.yygh.model.hosp.Hospital;
import top.songxs.yygh.model.hosp.HospitalSet;
import top.songxs.yygh.vo.hosp.HospitalQueryVo;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class HospitalServiceImpl implements HospitalService {

    @Autowired
    HospitalRepository hospitalRepository;
    @Autowired
    HospitalSetService hospitalSetService;

    @Autowired
    AckUtil ackUtil;

    @Autowired
    DictFeignClient dictFeignClient;

    @Override
    public void saveHospital(Map<String, String> map) {
        /*
    // 需求： 医院端调用该接口实现上传医院信息
    //1、 判断该医院是否开通了医院设置，并且状态status是否=1 ：如果权限不足，抛出自定义异常
    //2、 校验签名
    //3、 logoData中的空格替换成+
    //4、 医院的status默认设置1
    //5、 判断医院再mg中是否存在 ？ 添加 ： 修改
        */

        //获取医院编号 并根据医院编号进行查询医院信息
        String hoscode = map.get("hoscode");
        if (StringUtils.isEmpty(hoscode)) {
            throw new DiyException(20001, "医院编号为空！");
        }
        //如果查不出来  就是hospitalSet里面没有  就代表没有开通医院权限
        HospitalSet hospitalSet = hospitalSetService.getByHosCode(hoscode);
        if (hospitalSet == null) {
            throw new DiyException(20001, "未开通医院权限！");
        }
        //如果hospitalSet不是1的话 就代表没有开通医院权限 抛出自定义异常
        if (hospitalSet.getStatus() != 1) {
            throw new DiyException(20001, "未开通医院权限！");
        }
        //2 判断医院传过来的签名是否正确
        //这个签名是加密的 需要把数据库中的签名拿出来加密后比对
        String sign = map.get("sign");
        String encrypt = MD5.encrypt(hospitalSet.getSignKey());
        if (!encrypt.equalsIgnoreCase(sign)) {
            throw new DiyException(20001, "签名校验未通过！");
        }
        //将map转换为Hospital对象
        String s = JSONObject.toJSONString(map);
        Hospital hospital = JSONObject.parseObject(s, Hospital.class);
        // 处理status 和LogoData
        hospital.setStatus(1);
        hospital.setLogoData(hospital.getLogoData().replaceAll(" ", "+"));

        //根据hoscode去MG中查询Hospital对象 看是否已经存在，确定是新增还是更新操作

        Hospital hospitalFromMG = hospitalRepository.findByHoscode(hoscode);
        if (hospitalFromMG == null) {
            //不存在则为新增操作
            hospital.setCreateTime(new Date());
            hospital.setUpdateTime(new Date());
            hospitalRepository.save(hospital);
        } else {
            //存在则为修改操作
            hospital.setId(hospitalFromMG.getId());
            hospital.setCreateTime(hospitalFromMG.getCreateTime());
            hospital.setUpdateTime(new Date());
            hospitalRepository.save(hospital);
        }
    }


    @Override
    public Hospital show(Map<String, String> map) {
    // * .* .*.*(Map<String, String> map)

        //校验权限， 校验签名
        ackUtil.AckSign(map);

        String hoscode = map.get("hoscode");
        Hospital hospital = hospitalRepository.findByHoscode(hoscode);
        return hospital;
    }

    @Override
    public Page<Hospital> selectPage(Integer pageNum, Integer pageSize, HospitalQueryVo vo) {
        //条件分页查询  排序 模糊
        //分页条件对象
        PageRequest pageable = PageRequest.of(pageNum - 1, pageSize,
                Sort.by(Sort.Direction.DESC, "createTime"));

        //查询条件 需要封装为一个pojo对象
        Hospital hospital = new Hospital();
        BeanUtils.copyProperties(vo, hospital);
        //模糊查询使用的条件匹配器
        ExampleMatcher exampleMatcher = ExampleMatcher
                .matching()
                .withIgnoreCase(true) //忽略大小写
                .withStringMatcher(ExampleMatcher
                .StringMatcher.CONTAINING);//字符串包含

        //Example.of(hospital, exampleMatcher);  模糊查询
        //Example.of(hospital); 等值查询
        Example<Hospital> example = Example.of(hospital, exampleMatcher);
        Page<Hospital> pageResult = hospitalRepository.findAll(example, pageable);
        List<Hospital> list = pageResult.getContent();
        list.forEach(this::packHospital);

        return pageResult;
    }

    //修改医院的状态 上下线功能
    @Override
    public void updateStatus(String id, Integer status) {
        if (status == 1 || status == 0) {
            Hospital hospital = hospitalRepository.findById(id).get();

            //判断是否重复操作
            if (hospital.getStatus() == status){
                throw new DiyException(20001,"重复操作了！");
            }

            hospital.setStatus(status);
            hospital.setUpdateTime(new Date());
            hospitalRepository.save(hospital);
        }

    }

    @Override
    public Map<String, Object> showDetail(String id) {

        //根据id查询基本信息和预约规则信息
        Hospital hospital = hospitalRepository.findById(id).get();
        this.packHospital(hospital);
        Map<String, Object> map = new HashMap<>();
        map.put("bookingRule",hospital.getBookingRule());
        hospital.setBookingRule(null);
        map.put("hospital",hospital);
        return map;
    }

    @Override
    public Object getHospName(String hoscode) {

        Hospital hos = hospitalRepository.findByHoscode(hoscode);

        if (hos != null) {
            return hos.getHosname();
        }
        return null;

    }

    @Override
    public List<Hospital> findByHosName(String hosname) {
        List<Hospital> lists = hospitalRepository.findHospitalByHosnameLike(hosname);
        lists.forEach(this::packHospital);
        return lists;
    }

    //选中某个医院写一个医院调用，显示医院的基本信息和预约规则信息
    @Override
    public Map<String, Object> item(String hoscode) {
        Map<String, Object> result = new HashMap<>();
        //医院详情
        Hospital hospital = getHospitalByhoscede(hoscode);
        this.packHospital(hospital);
        result.put("hospital", hospital);
        //预约规则
        result.put("bookingRule", hospital.getBookingRule());
        //不需要重复返回
        hospital.setBookingRule(null);
        return result;
    }

    @Override
    public Hospital getByHosCode(String hoscode) {
        Hospital hospital = hospitalRepository.getByHoscode(hoscode);


        return hospital;
    }

    private Hospital getHospitalByhoscede(String hoscode) {
    Hospital hospital = hospitalRepository.findByHoscode(hoscode);
    return hospital;

}


    private void packHospital(Hospital hospital) {
        //省市区的value值
        String provinceCode =hospital.getProvinceCode();
        String cityCode = hospital.getCityCode();
        String districtCode = hospital.getDistrictCode();
        //医院等级value值
        String hostype = hospital.getHostype();

        String provinceStr = dictFeignClient.getName(provinceCode);
        String cityStr = dictFeignClient.getName(cityCode);
        String districtStr = dictFeignClient.getName(districtCode);
        String hospitalStr = dictFeignClient.getHospitalName(hostype, "Hostype");
        //拼接医院的详细地址
        String fullAddress = provinceStr + cityStr + districtStr+hospital.getAddress();
        //每一个医院对象附加了两个属性值，存入到了param中
        hospital.getParam().put("hospitalString",hospitalStr);//医院的等级名称
        hospital.getParam().put("fullAddress",fullAddress);//医院端的详细地址











    }


}
